import 'dart:io';
import 'dart:typed_data';
import 'dart:ui';

import 'package:easy_chat_app/commons/utils/HttpUtils.dart';
import 'package:easy_chat_app/commons/utils/RouteUtils.dart';
import 'package:extended_image/extended_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:image_editor/image_editor.dart' as ImageEditor;
import 'package:logger/logger.dart';
import 'package:provider/provider.dart';

class MobileUserHeadPortraitPreviewPageChangeNotifier with ChangeNotifier {
  MobileUserHeadPortraitPreviewPageChangeNotifier(
      {EditImageInfo? editImageInfo})
      : _editImageInfo = editImageInfo;

  EditImageInfo? _editImageInfo;

  void setEditImageInfo(EditImageInfo editImageInfo) {
    _editImageInfo = editImageInfo;
    notifyListeners();
  }

  EditImageInfo? getEditImageInfo() {
    return _editImageInfo;
  }
}

class MobileUserHeadPortraitPreviewPage extends StatefulWidget {
  const MobileUserHeadPortraitPreviewPage({super.key});

  @override
  State<StatefulWidget> createState() {
    return _MobileUserHeadPortraitPreviewPage();
  }
}

class _MobileUserHeadPortraitPreviewPage
    extends State<MobileUserHeadPortraitPreviewPage> {
  Logger logger = Logger();

  @override
  Widget build(BuildContext context) {
    RouteSettings routeSettings = RouteUtils.currentRouteSettings();
    var pageParams =
        routeSettings.arguments as MobileUserHeadPortraitPreviewPageParams?;
    var file = pageParams?.xFile;
    logger.i("file:${file!.path}");
    final size = MediaQuery.of(context).size;
    final width = size.width;

    ImageEditorController editorController = ImageEditorController();
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (context) {
          return MobileUserHeadPortraitPreviewPageChangeNotifier();
        })
      ],
      builder: (context, child) {
        var editImageInfo = context
            .watch<MobileUserHeadPortraitPreviewPageChangeNotifier>()
            .getEditImageInfo();
        ExtendedImageProvider? extendedImageProvider;
        if (editImageInfo != null) {
          extendedImageProvider = ExtendedMemoryImageProvider(
              editImageInfo.data!,
              cacheRawData: true);
        } else {
          extendedImageProvider =
              ExtendedFileImageProvider(File(file.path), cacheRawData: true);
        }
        return Scaffold(
          backgroundColor: Colors.black,
          appBar: AppBar(
            backgroundColor: Colors.black,
            leading: const BackButton(
              color: Colors.white,
            ),
          ),
          body: Container(
              color: Colors.black,
              height: double.infinity,
              width: double.infinity,
              alignment: Alignment.center,
              child: Stack(
                children: [
                  ExtendedImage(
                      width: double.infinity,
                      height: double.infinity,
                      fit: BoxFit.contain,
                      mode: ExtendedImageMode.editor,
                      initEditorConfigHandler: (state) {
                        return EditorConfig(
                            maxScale: 8.0,
                            hitTestSize: 20.0,
                            cropAspectRatio: 1,
                            controller: editorController,
                            editorMaskColorHandler:
                                (BuildContext context, bool pointerDown) {
                              return Colors.black
                                  .withOpacity(pointerDown ? 0 : 0.4);
                            });
                      },
                      image: extendedImageProvider),
                  Positioned(
                      bottom: 10,
                      child: SizedBox(
                        height: 120,
                        width: width,
                        child: Column(
                          children: [
                            Row(
                              children: [
                                IconButton(
                                    onPressed: () {
                                      editorController.rotate();
                                    },
                                    icon: const Icon(
                                      Icons.rotate_right_outlined,
                                      color: Colors.white,
                                    )),
                                const Spacer(),
                                TextButton(
                                    onPressed: () {
                                      editorController.reset();
                                    },
                                    child: const Text(
                                      "还原",
                                      style: TextStyle(color: Colors.white),
                                    ))
                              ],
                            ),
                            const Divider(
                              height: 1,
                              color: Color.fromRGBO(55, 55, 55, 1),
                            ),
                            Row(
                              children: [
                                TextButton(
                                    onPressed: () {
                                      RouteUtils.pop();
                                    },
                                    child: const Text(
                                      "取消",
                                      style: TextStyle(color: Colors.white),
                                    )),
                                const Spacer(),
                                TextButton(
                                    onPressed: () async {
                                      editImageInfo =
                                          await cropImageDataWithNativeLibrary(
                                              editorController);
                                      if (editImageInfo != null) {
                                        var result = await HttpUtils
                                            .uploadUserHeadPortrait(
                                                editImageInfo!);
                                        logger.i("头像上传成功: $result");
                                        RouteUtils.pop();
                                      }
                                    },
                                    child: const Text(
                                      "完成",
                                      style: TextStyle(color: Colors.white),
                                    ))
                              ],
                            )
                          ],
                        ),
                      ))
                ],
              )),
        );
      },
    );
  }
}

enum ImageType { gif, jpg }

class EditImageInfo {
  EditImageInfo(
    this.data,
    this.imageType,
  );

  final Uint8List? data;
  final ImageType imageType;
}

Future<EditImageInfo> cropImageDataWithNativeLibrary(
    ImageEditorController imageEditorController) async {
  final EditActionDetails action = imageEditorController.editActionDetails!;

  final Uint8List img = imageEditorController.state!.rawImageData;

  final ImageEditor.ImageEditorOption option = ImageEditor.ImageEditorOption();

  if (action.hasRotateDegrees) {
    final int rotateDegrees = action.rotateDegrees.toInt();
    option.addOption(ImageEditor.RotateOption(rotateDegrees));
  }
  if (action.flipY) {
    option.addOption(
        const ImageEditor.FlipOption(horizontal: true, vertical: false));
  }

  if (action.needCrop) {
    Rect cropRect = imageEditorController.getCropRect()!;
    if (imageEditorController.state!.widget.extendedImageState.imageProvider
        is ExtendedResizeImage) {
      final ImmutableBuffer buffer = await ImmutableBuffer.fromUint8List(img);
      final ImageDescriptor descriptor = await ImageDescriptor.encoded(buffer);

      final double widthRatio =
          descriptor.width / imageEditorController.state!.image!.width;
      final double heightRatio =
          descriptor.height / imageEditorController.state!.image!.height;
      cropRect = Rect.fromLTRB(
        cropRect.left * widthRatio,
        cropRect.top * heightRatio,
        cropRect.right * widthRatio,
        cropRect.bottom * heightRatio,
      );
    }
    option.addOption(ImageEditor.ClipOption.fromRect(cropRect));
  }

  Uint8List? result = await ImageEditor.ImageEditor.editImage(
    image: img,
    imageEditorOption: option,
  );

  result = await FlutterImageCompress.compressWithList(result!,
      minHeight: 400, minWidth: 400);

  return EditImageInfo(result, ImageType.jpg);
}
